import store from "../utils/store";
import * as antdHelper from "../utils/antd-helper";
import * as graphql from "./graphql";
import * as oss from "./oss";
import * as evm from "./evm";
import { Modal, Progress, notification } from "antd";
import { formatterSizeStr } from "../utils/formatter";
import webconfig from "../webconfig";
window.uploadingList = [];
window.isUploading = false;

export function uploadFiles(territoryId, containerId, territoryName, files) {
  return new Promise((resolve, reject) => {
    let file = files.pop();
    uploadFile(territoryId, containerId, territoryName, file, function () {
      while (files.length > 0) {
        file = files.pop();
        uploadFile(territoryId, containerId, territoryName, file, () => { });
      }
      resolve();
    });
  });
}
export async function uploadFile(territoryId, containerId, territoryName, file, readyCb) {
  let ret = {};
  let accountType = store.get("accountType");
  let account = store.get("account");
  let uping = {
    id: new Date().valueOf(),
    per: 0,
    name: file.name,
    size: file.size,
    sizeStr: formatterSizeStr(file.size),
    state: "waiting",
  };
  let listHistory = initUploadingList();
  let blockIndex = 0, historyItem;
  if (listHistory) {
    historyItem = listHistory.find(t => t.name == uping.name && t.size == uping.size);
    if (historyItem && historyItem.blockIndex) {
      uping.state = 'pending';
      blockIndex = historyItem.blockIndex + 1;
    }
  }
  window.uploadingList.push(uping);
  checkIsUploading();
  window.refreshUploadingFiles();
  const progressCb = (t) => {
    if (uping.state == "cancel") {
      return;
    }
    let p = t.percentComplete;
    if (p >= 100) {
      p = 99;
    }
    uping.blockIndex = t.blockIndex;
    if (t.message && t.signedMsg) {
      uping.message = t.message;
      uping.signedMsg = t.signedMsg;
      if (setSignResult(t.message, t.signedMsg)) {
        readyCb();
        readyCb = () => { };
      }
    }
    uping.per = p;
    uping.state = uping.state == 'waiting' ? "pending" : uping.state;
    uping.speed = t.speed + t.speedUnit;
    let xhr = t.xhr;
    uping.stop = function () {
      console.log("user cancel upload.");
      xhr.abort();
      // xhr.upload.onprogress = null;
      // xhr.upload.onload = null;
      // xhr.upload.onerror = null;
      // xhr.upload.onabort = null;
      setTimeout(function () {
        uping.state = "cancel";
        uping.speed = "";
        window.refreshUploadingFiles();
        checkIsUploading();
      }, 500);
    };
    uping.pause = function () {
      console.log('pausing.')
      xhr.pause();
      uping.state = "pause";
      uping.speed = "";
      window.refreshUploadingFiles();
      checkIsUploading();
    }
    uping.resume = function () {
      xhr.resume();
      uping.state = "pending";
      window.refreshUploadingFiles();
      checkIsUploading();
    }
    // console.log(window.uploadingList);
    window.refreshUploadingFiles();
    checkIsUploading();
    storeUploadingList();
  };
  let message = "<Bytes>cess-js-sdk-frontend-" + new Date().valueOf() + "</Bytes>";
  uping.message = message;
  let signedMsg = null;
  if (blockIndex && historyItem) {
    message = historyItem.message;
    signedMsg = historyItem.signedMsg;
  }
  let signHistory = getSignResult();// store.get("signmsg-" + account.address);
  if (!signedMsg && signHistory && signHistory.signedMsg) {
    message = signHistory.message;
    uping.message = message;
    signedMsg = signHistory.signedMsg;
    uping.signedMsg = signedMsg;
  }
  try {
    if (accountType == "email") {
      if (!signedMsg) {
        ret = await graphql.getSignMessage(message);
        if (ret.msg != 'ok' || !ret.data?.getSignMessage?.signedMsg) {
          return antdHelper.alertError(ret.msg);
        }
        signedMsg = ret.data.getSignMessage.signedMsg;
        uping.signedMsg = signedMsg;
      }
      if (setSignResult(message, signedMsg)) {
        readyCb();
        readyCb = () => { };
      }
      readyCb = () => { };
      ret = await oss.uploadFile(file, territoryName, progressCb, message, signedMsg, null, blockIndex);
      if (ret?.msg == "ok" && ret?.data?.fid) {
        ret = await graphql.newFileMap(ret.data.fid, file.name, territoryId, containerId);
      }
    } else if (accountType == "evm") {
      if (!signedMsg) {
        signedMsg = await evm.signMsg(message);
        // console.log('account', account)
        uping.signedMsg = signedMsg;
      }
      if (setSignResult(message, signedMsg)) {
        readyCb();
        readyCb = () => { };
      }
      readyCb = () => { };
      ret = await oss.uploadFile(file, territoryName, progressCb, message, signedMsg, account.evmAddress, blockIndex);
      if (ret?.msg == "ok" && ret?.data?.fid) {
        ret = await graphql.newFileMap(ret.data.fid, file.name, territoryId, containerId);
      }
    }
    else {
      // setSignResult(account, message, signedMsg);      
      ret = await oss.uploadFile(file, territoryName, progressCb, message, signedMsg, null, blockIndex);
      if (ret?.msg == "ok" && ret?.data?.fid) {
        ret = await graphql.newFileMap(ret.data.fid, file.name, territoryId, containerId);
      }
    }
  } catch (error) {
    ret.msg = error.message;
  }
  if (!ret) {
    uping.state = "fail";
    return false;
  }
  if (ret.msg == "abort") {
    uping.state = "abort";
    return false;
  }
  if (ret.msg != "ok") {
    antdHelper.alertError(ret.msg);
    uping.state = "error";
    uping.error = ret.msg;
    return false;
  }
  antdHelper.notiOK("Upload success : " + file.name);
  uping.per = 100;
  uping.state = "success";
  // console.log(window.uploadingList);
  window.refreshUploadingFiles();
  checkIsUploading();
  if (window.refreshFileList) {
    window.refreshFileList();
  }
  if (window.refreshSpace) {
    window.refreshSpace();
  }
}
export async function deleteFiles(selectItems) {
  let ret = {};
  try {
    let accountType = store.get("accountType");
    let account = store.get("account");
    let message = "<Bytes>cess-js-sdk-frontend-" + new Date().valueOf() + "</Bytes>";
    let signedMsg = null;
    let signHistory = getSignResult();
    if (signHistory?.signedMsg && signHistory?.message) {
      message = signHistory.message;
      signedMsg = signHistory.signedMsg;
    } else {
      if (accountType == "email") {
        ret = await graphql.getSignMessage(message);
        if (ret.msg != 'ok' || !ret.data?.getSignMessage?.signedMsg) {
          antdHelper.alertError(ret.msg);
          return ret;
        }
        signedMsg = ret.data.getSignMessage.signedMsg;
      }
      else if (accountType == "evm") {
        signedMsg = await evm.signMsg(message);
      } else {
        signedMsg = await oss.authSign(account.address, message);
      }
      if (signedMsg) {
        setSignResult(message, signedMsg);
      } else {
        antdHelper.alertError('sign error');
        return ret;
      }
    }
    let successCount = 0;
    if (!Array.isArray(selectItems)) {
      selectItems = [selectItems];
    }
    for (let item of selectItems) {
      let fid = item.fid;
      if (accountType != "email") {
        ret = await oss.deleteFile(fid, message, signedMsg);
        if (ret.msg != 'ok') {
          console.error(ret.msg);
          // return ret;
        }
      }
      ret = await graphql.deleteFileMap(item.id);
      if (ret.msg != 'ok') {
        antdHelper.alertError(ret.msg);
        return ret;
      }
      successCount++;
    }
    antdHelper.notiOK(`Deleted ${successCount} file`);
    ret = { msg: 'ok' };
  } catch (error) {
    ret.msg = error.message;
    antdHelper.alertError(ret.msg);
  }
  return ret;
}
function checkIsUploading() {
  window.isUploading = window.uploadingList.find((t) => t.state == "pending")
    ? true
    : false;
  if (window.isUploading) {
    window.onbeforeunload = function (e) {
      e = e | window.event;
      if (e) {
        e.returnValue = "Close tips";
      }
      return false;
    };
  } else {
    window.onbeforeunload = null;
  }
}
function storeUploadingList() {
  let userId = store.get("userId");
  let list = window.uploadingList.filter((t) => t.state == "pending" || t.state == "waiting" || t.state == "pause");
  store.set('uploading-files-' + userId, list);
}
function initUploadingList() {
  let userId = store.get("userId");
  let list = store.get('uploading-files-' + userId);
  if (!window.abortFileList && list && list.length > 0) {
    window.abortFileList = list;
    return list;
  } else {
    return null;
  }
}
export function setSignResult(message, signedMsg) {
  if (message && signedMsg) {
    let account = store.get("account");
    store.set("signmsg-" + account.address, { message, signedMsg });
    return true;
  }
  return false;
}
export function getSignResult() {
  let account = store.get("account");
  let signHistory = store.get("signmsg-" + account.address);
  if (signHistory && signHistory.signedMsg) {
    return signHistory;
  }
  return null;
}
